package com.mall.user.services;

import com.alibaba.fastjson.JSON;
import com.mall.commons.tool.exception.ValidateException;
import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.converter.UserConverterMapper;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dal.persistence.UserVerifyMapper;
import com.mall.user.dto.*;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.HashMap;
import java.util.List;

/**
 * @Author: 尹圣淼
 * @Date: 2022/1/21 9:28
 */
@Slf4j
@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserConverterMapper userConverterMapper;

    @Autowired
    UserVerifyMapper userVerifyMapper;


    @Override
    public CheckAuthResponse validToken(CheckAuthRequest checkAuthRequest) {
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();
        String userInfo;  // userInfo是json字符串
        try {
            // 判空操作
            checkAuthRequest.requestCheck();
            userInfo = JwtTokenUtils.builder().token(checkAuthRequest.getToken()).build().freeJwt();
            log.info("validToken" + userInfo);
        } catch (ValidateException e) {
            // 解析 jwt失败
            checkAuthResponse.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
            checkAuthResponse.setMsg(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
            return checkAuthResponse;
        }
        checkAuthResponse.setUserInfo(userInfo);
        // 打印日志
        log.info("用户验证登录成功,登录参数request:{}", JSON.toJSONString(checkAuthRequest));
        checkAuthResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        checkAuthResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        return checkAuthResponse;
    }


    @Override
    public UserLoginResponse login(UserLoginRequest userLoginRequest) {
        // 用作返回值。
        UserLoginResponse userLoginResponse = new UserLoginResponse();
        // 先进行判空。
        userLoginRequest.requestCheck();

        // 加密后 方可与数据库中的进行比对。
        // (用密码进行加密  。)
        String pwd = DigestUtils.md5DigestAsHex(userLoginRequest.getPassword().getBytes());
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("username", userLoginRequest.getUserName())
                .andEqualTo("password", pwd);
        List<Member> members = memberMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(members)) {
            // 为空 就是没有该用户。  =>  并没有注册。
            // 也可以是理解为密码错误。
            userLoginResponse.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
            userLoginResponse.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
            return userLoginResponse;
        }

        // 如果有 还要进行查询是否被激活。
        Member member = members.get(0);
        if ("N".equals(member.getIsVerified())) {
            // 这是未激活。
            userLoginResponse.setCode(SysRetCodeConstants.USER_ISVERFIED_ERROR.getCode());
            userLoginResponse.setMsg(SysRetCodeConstants.USER_ISVERFIED_ERROR.getMessage());
            return userLoginResponse;
        }

        // 走到这，证明即被注册了，也是被激活了。
        // 即 登陆成功。  验证成功。

        UserLoginResponse converter = userConverterMapper.converter(member);
        // 验证成功： 将封装到token中的数据取出（包含用户名 和id 的map）
        // 放入到所拦截的请求对象的 名为"userInfo"的属性中。
        String userInfo = null;
        HashMap<String, Object> map = new HashMap<>();
        map.put("uid", member.getId());
        map.put("file", member.getFile());// 无需防空。有默认的.
        map.put("username", member.getUsername());
        userInfo = JSON.toJSONString(map);
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();
        checkAuthResponse.setUserInfo(userInfo);
        // 根据userInfo 生成token
        String token = JwtTokenUtils.builder().msg(userInfo).build().creatJwtToken();
        // 放。  下次要用。
        userLoginResponse.setToken(token);
        log.info("用户登录成功,登录参数request:{}", JSON.toJSONString(userLoginRequest));
        userLoginResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        userLoginResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
//        userLoginResponse.setId(member.getId());
//        userLoginResponse.setUsername(member.getUsername());
        return userLoginResponse;
    }
}
